package com.lanchetech.service.impl;

import com.baidu.fsg.uid.UidGenerator;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.lanchetech.bean.response.BaseResp;
import com.lanchetech.bean.vo.CardConsumptionUserVo;
import com.lanchetech.bean.vo.OrderSkuVO;
import com.lanchetech.common.enums.*;
import com.lanchetech.dao.*;
import com.lanchetech.entity.*;
import com.lanchetech.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class CommonAfterSaleServiceImpl implements CommonAfterSaleService {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    OrderDiscountMapper orderDiscountMapper;

    @Autowired
    CouponMapper couponMapper;

    @Autowired
    OrderSkuMapper orderSkuMapper;

    @Value("${domain.url}")
    private String domainUrl;


    @Value("${wx.pay.appId}")
    private String miniAppId;

    @Value("${wx.app.appId}")
    private String appAppId;

    @Autowired
    AfterSaleMapper afterSaleMapper;

    @Autowired
    OrdersMapper ordersMapper;

    @Autowired
    WxPayService wxPayService;

    @Resource
    UidGenerator uidGenerator;

    @Autowired
    OrderPayMapper orderPayMapper;

    @Autowired
    TenantMapper tenantMapper;

    @Autowired
    CardFlowMapper cardFlowMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    UserCommissionMapper userCommissionMapper;

    @Autowired
    TenantFlowMapper tenantFlowMapper;

    @Autowired
    ConsumptionService consumptionService;

    @Autowired
    RewardQueueMapper rewardQueueMapper;

    @Autowired
    BonusCountMapper bonusCountMapper;

    @Autowired
    SkuMapper skuMapper;

    @Autowired
    SpuMapper spuMapper;

    @Autowired
    FinanceService financeService;

    @Autowired
    InviteFirstBuyMapper inviteFirstBuyMapper;

    @Autowired
    CommissionService commissionService;

    @Autowired
    HipoConfigMapper hipoConfigMapper;

    @Autowired
    GiveMemberRecordMapper giveMemberRecordMapper;

    @Autowired
    IdentityMapper identityMapper;

    @Autowired
    DaoService daoService;

    @Autowired
    DividendPrecipitationMapper dividendPrecipitationMapper;

    @Autowired
    GroupsPerformanceMapper groupsPerformanceMapper;

    @Autowired
    ShareholderPerformanceMapper shareholderPerformanceMapper;

    @Autowired
    FlashSaleSpuMapper flashSaleSpuMapper;

    @Autowired
    FlashSaleSkuMapper flashSaleSkuMapper;

    @Autowired
    private CardConsumptionUserMapper cardConsumptionUserMapper;

    @Autowired
    private UserAmtLogMapper userAmtLogMapper;

    @Override
    public BaseResp commonAgreeRefund(AfterSale req) {
        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(req.getId());
        Orders orders = ordersMapper.selectByPrimaryKey(afterSale.getOrderId());

        if (afterSale.getApplyAmount().compareTo(req.getRefundAmount()) == -1) {
            return new BaseResp(ResultCode.REFUND_EXCEED_PAID);
        }

        if (orders.getTotalRefundAmount().add(req.getRefundAmount()).compareTo(orders.getTotalPayAmount()) > 0) {
            return new BaseResp(ResultCode.OVER_PAID);
        }

        boolean isOnlyRefund = AfterSaleTypeEnum.ONLY_REFUND.getType().equals(afterSale.getType()) && AfterSaleStatusEnum.PROCESSING.getStatus().equals(afterSale.getStatus());
        boolean isReturnRefund = AfterSaleTypeEnum.RETURN_REFUND.getType().equals(afterSale.getType()) && AfterSaleStatusEnum.CONFIRM.getStatus().equals(afterSale.getStatus());

        if (isOnlyRefund || isReturnRefund) {

            // 扣除商户余额，不足的则扣成负数，按orderSku中的payAmount和tenantAmount比例进行同等扣除
            OrderSku orderSku = orderSkuMapper.selectByPrimaryKey(afterSale.getOrderSkuId());
            BigDecimal tenantRefund = BigDecimal.ZERO;
            if (orderSku.getTenantAmount().compareTo(BigDecimal.ZERO) > 0) {
                tenantRefund = req.getRefundAmount()
                        .multiply(orderSku.getTenantAmount().divide(orderSku.getPayAmount(), 2, BigDecimal.ROUND_HALF_DOWN))
                        .setScale(2, BigDecimal.ROUND_HALF_DOWN);
            }

            //如果订单使用了优惠券
            OrderDiscount orderDiscount = orderDiscountMapper.findOneByOrderIdAndType(afterSale.getOrderId(), PromotionEnum.COUPON.getPromotion());
            if (orderDiscount != null) {
                Coupon coupon = couponMapper.selectByPrimaryKey(orderDiscount.getRelateId());
                BigDecimal eachCouponAmount = BigDecimal.ZERO;
                if (OrderDiscountLevelEnum.ORDER_LEVEL.getType().equals(orderDiscount.getLevel())) {
                    //订单级优惠券
                    List<OrderSkuVO> orderSkuVOList = orderSkuMapper.findAllByOrderId(afterSale.getOrderId());
                    BigDecimal totalPayAmount = orderSkuVOList.stream().map(item -> item.getPayAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
                    //orderSku分摊优惠券金额
                    eachCouponAmount = orderSku.getPayAmount().divide(totalPayAmount, 2, BigDecimal.ROUND_HALF_DOWN).multiply(coupon.getDiscountAmount()).setScale(2, BigDecimal.ROUND_HALF_DOWN);
                } else if (OrderDiscountLevelEnum.SPU_LEVEL.getType().equals(orderDiscount.getLevel())) {
                    //商品级优惠券
                    if (afterSale.getSpuId().equals(coupon.getSpuId())) {
                        eachCouponAmount = coupon.getDiscountAmount();
                    }
                }
                BigDecimal tenantAmountRate = orderSku.getTenantAmount().divide(orderSku.getPayAmount(), 2, BigDecimal.ROUND_HALF_DOWN);
                //商户优惠券
                if (PlatformTypeEnum.MERCHANT.getType().equals(coupon.getPlatformType())) {
                    BigDecimal platformCouponRate = BigDecimal.ONE.subtract(tenantAmountRate);
                    BigDecimal platformCouponAmount = eachCouponAmount.multiply(platformCouponRate).setScale(2, BigDecimal.ROUND_HALF_DOWN);
                    tenantRefund = tenantRefund.subtract(platformCouponAmount);
                }
                //平台优惠券
                if (PlatformTypeEnum.PLATFORM.getType().equals(coupon.getPlatformType())) {
                    tenantRefund = (req.getRefundAmount().add(eachCouponAmount)).multiply(tenantAmountRate).setScale(2, BigDecimal.ROUND_HALF_DOWN);
                }

            }

            // 必须有足够的余额，才可以进行退款
            Tenant tenant = tenantMapper.selectByPrimaryKey(orders.getTenantId());
            if (tenant.getPoint().compareTo(tenantRefund) < 0) {
                return new BaseResp(ResultCode.TENANT_POINT_NOT_ENOUGH);
            }


            // 生成退款订单号
            String refundNo = Long.toString(uidGenerator.getUID());
            // 状态在退款成功的回调中更新
            afterSale.setRefundNo(refundNo);
            afterSale.setDealRemark(req.getDealRemark());
            afterSale.setRefundAmount(req.getRefundAmount());
            afterSale.setDealTime(new Date());
            afterSale.setTenantAmount(tenantRefund);
            afterSaleMapper.updateByPrimaryKeySelective(afterSale);

            // 更新代付状态
            if (PayTypeEnum.ANOTHER_APY.getType().equals(orders.getPayType())) {
                Byte status = OrderPayStatusEnum.FULL_REFUND.getStatus();

                if (orders.getTotalRefundAmount().add(afterSale.getRefundAmount()).compareTo(orders.getTotalPayAmount()) < 0) {
                    status = OrderPayStatusEnum.PART_REFUND.getStatus();
                }

                orderPayMapper.updateStatusAndUpdatedAtByTradeNo(status, new Date(), orders.getTradeNo());
            }

            if (PayTypeEnum.WECHAT.getType().equals(orders.getPayType())
                    || PayTypeEnum.ANOTHER_APY.getType().equals(orders.getPayType())
                    || PayTypeEnum.APP_WECHAT.getType().equals(orders.getPayType())
            ) {
                if (orders.getTotalPayAmount().compareTo(BigDecimal.ZERO) > 0) {
                    WxPayRefundRequest request = WxPayRefundRequest.newBuilder()
                            //订单号
                            .outTradeNo(afterSale.getTradeNo())
                            //退款订单号
                            .outRefundNo(refundNo)
                            //原先总金额(分)
                            .totalFee(orders.getTotalPayAmount().multiply(new BigDecimal(100)).intValue())
                            //退款金额(分)
                            .refundFee(afterSale.getRefundAmount().multiply(new BigDecimal(100)).intValue())
                            //退款回调
                            .notifyUrl(domainUrl + "/admin-api/after-sale/refundNotify")
                            .build();

                    WxPayRefundResult wxPayRefundResult;
                    try {
                        wxPayService.getConfig().setAppId(PayTypeEnum.APP_WECHAT.getType().equals(orders.getPayType()) ? appAppId : miniAppId);
                        wxPayService.getConfig().setTradeType(PayTypeEnum.APP_WECHAT.getType().equals(orders.getPayType()) ? "APP" : "JSAPI");

                        wxPayRefundResult = wxPayService.refund(request);
                        //判断退款信息是否正确
                        if ("SUCCESS".equals(wxPayRefundResult.getReturnCode()) && "SUCCESS".equals(wxPayRefundResult.getResultCode())) {
                            log.info("微信退款请求已经成功发送");
                            if (WxPayErrCodeEnum.SYSTEMERROR.getCode().equals(wxPayRefundResult.getErrCode())
                                    || WxPayErrCodeEnum.BIZERR_NEED_RETRY.getCode().equals(wxPayRefundResult.getErrCode())) {
                                log.error("微信退款请求，重新发送");
                                wxPayRefundResult = wxPayService.refund(request);
                                if ("SUCCESS".equals(wxPayRefundResult.getReturnCode()) && "SUCCESS".equals(wxPayRefundResult.getResultCode())) {
                                    log.info("微信退款请求重新发送成功");
                                } else {
                                    log.error("微信退款请求重新发送失败");
                                }
                            }
                            // 是否为消费金商品
                            if (orderSku.getActivityType().equals(ActivityEnum.CONSUMPTION_FUND.getActivity())) {
                                returnConsumption(orderSku);
                            }
                            return new BaseResp();
                        } else {
                            log.error("微信退款请求发送失败");
                        }
                    } catch (WxPayException e) {
                        log.error("微信退款接口错误信息= {}", e);
                    }
                    return new BaseResp(ResultCode.FAIL);
                } else {
                    return new BaseResp();
                }
            } else {
                // 嗨币退款
                User user = userMapper.selectByPrimaryKey(orders.getUserId());
                BigDecimal cardPoint = user.getCardPoint().add(afterSale.getRefundAmount());
                userMapper.updateCardPointById(cardPoint, user.getId());

                cardFlowMapper.insert(CardFlow.builder()
                        .userId(user.getId())
                        .amount(afterSale.getRefundAmount())
                        .tradeType(CardTradeTypeEnum.REFUND.getTradeType())
                        .type(CardTradeTypeEnum.REFUND.getType())
                        .cardPoint(cardPoint)
                        .relateId(afterSale.getId())
                        .remark("订单售后退款")
                        .createdAt(new Date())
                        .build());

                refundNotifyComplete(afterSale.getRefundNo());
                // 是否为消费金商品
                if (orderSku.getActivityType() != null && orderSku.getActivityType().equals(ActivityEnum.CONSUMPTION_FUND.getActivity())) {
                    log.info("消费金商品退款");
                    returnConsumption(orderSku);
                }
                return new BaseResp();
            }
        } else {
            return new BaseResp(ResultCode.FAIL);
        }
    }

    private void returnConsumption(OrderSku orderSku) {
        // 获取用户消费金账户
        CardConsumptionUserVo cardConsumptionUser = cardConsumptionUserMapper.getCardConsumptionUser(orderSku.getUserId());
        if (cardConsumptionUser != null) {
            // 生成记录
            UserAmtLog userAmtLog = new UserAmtLog();
            userAmtLog.setUserId(cardConsumptionUser.getUserId());
            userAmtLog.setAmt(orderSku.getDiscountPrice());
            userAmtLog.setBeforeAmt(cardConsumptionUser.getAmt());
            userAmtLog.setAfterAmt(cardConsumptionUser.getAmt().add(orderSku.getDiscountPrice()));
            userAmtLog.setType((byte) 1);
            userAmtLog.setCreated(new Date());
            userAmtLog.setRemark("订单退款返还消费金:+" + orderSku.getDiscountPrice());
            userAmtLogMapper.insert(userAmtLog);
            // 返还消费金
            cardConsumptionUser.setAmt(cardConsumptionUser.getAmt().add(orderSku.getDiscountPrice()));
            cardConsumptionUserMapper.updateConsumptionUser(cardConsumptionUser);
        }
    }

    @Override
    public void refundNotifyComplete(String refundNo) {
        afterSaleMapper.updateStatusByRefundNo(AfterSaleStatusEnum.REFUNDED.getStatus(), refundNo);

        // 更新订单中总退款金额
        AfterSale afterSale = afterSaleMapper.findOneByRefundNo(refundNo);
        Orders orders = ordersMapper.findOneByTradeNo(afterSale.getTradeNo());
        OrderSku orderSku = orderSkuMapper.selectByPrimaryKey(afterSale.getOrderSkuId());
        BigDecimal refundAmount = orders.getTotalRefundAmount().add(afterSale.getRefundAmount());
        if (orders.getTotalPayAmount().compareTo(refundAmount) == 0) {
            ordersMapper.updateStatusById(OrdersStatusEnum.CLOSE.getStatus(), orders.getId());
        }
        ordersMapper.updateTotalRefundAmountById(refundAmount, orders.getId());
        // 退款后，库存不更新

        //退款后更新销量
        spuMapper.subSalesById(afterSale.getCount(), afterSale.getSpuId());
        skuMapper.subSalesById(afterSale.getCount(), afterSale.getSkuId());
        if (ActivityEnum.FLASH_SALE.getActivity().equals(orderSku.getActivityType())) {
            //秒杀更新销量
            flashSaleSkuMapper.refundStockAndSalesByActivityIdAndSkuId(afterSale.getCount(), orderSku.getActivityId(), afterSale.getSkuId());
            flashSaleSpuMapper.refundSalesAndUpdatedAtByActivityIdAndSpuId(afterSale.getCount(), new Date(), orderSku.getActivityId(), afterSale.getSpuId());
        }

        //会员商品退款扣减到期时间
        String memberSpu = daoService.getHipoConfigValue(HipoConfigEnum.MEMBER_SPU.getConfig());
        if (orderSku.getSpuId().equals(memberSpu)) {
            Date date = new Date();
            Identity identity = identityMapper.findOneByUserId(orders.getUserId());
            if (identity.getMemberExpireTime() != null) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(identity.getMemberExpireTime());
                calendar.add(Calendar.YEAR, -afterSale.getCount() * 2);
                identityMapper.updateMemberExpireTimeAndUpdateAtByUserId(calendar.getTime().before(date) ? date : calendar.getTime(), date, orders.getUserId());
            }
        }


        // 冻结中的佣金，要被扣回
        UserCommission userCommission = userCommissionMapper.findOneByOrderSkuId(afterSale.getOrderSkuId());
        if (userCommission != null) {
            // 判断佣金是否是冻结状态
            if (userCommission.getStatus().equals(UserCommissionStatusEnum.FREEZE.getStatus())) {
                userCommission.setStatus(UserCommissionStatusEnum.REFUND.getStatus());
                userCommission.setUpdatedAt(new Date());
                userCommissionMapper.updateByPrimaryKey(userCommission);

                // 将主播佣金和合伙人的主播收入退还给商家
                if (UserCommissionTypeEnum.ANCHOR_COMMISSION.getType().equals(userCommission.getType())
                        || UserCommissionTypeEnum.PARTNER_ANCHOR_COMMISSION.getType().equals(userCommission.getType())) {
                    Tenant tenant = tenantMapper.selectByPrimaryKey(orders.getTenantId());
                    tenantFlowMapper.insert(TenantFlow.builder()
                            .amount(userCommission.getCommission())
                            .tradeType(TenantTradeTypeEnum.ANCHOR_COMMISSION_REFUND.getTradeType())
                            .type(TenantTradeTypeEnum.ANCHOR_COMMISSION_REFUND.getType())
                            .point(tenant.getPoint().add(userCommission.getCommission()))
                            .relateId(orders.getId())
                            .remark(userCommission.getRemark())
                            .createdAt(new Date())
                            .tenantId(tenant.getId())
                            .build());
                    tenantMapper.updatePointById(tenant.getPoint().add(userCommission.getCommission()), tenant.getId());
                }
            }
        }

        // 创建消费记录
        consumptionService.updateConsumptionAmount(ConsumptionRecord.builder()
                .userId(orders.getUserId())
                .amount(afterSale.getRefundAmount())
                .recordType(ConsumptionRecordTypeEnum.REFUND.getRecordType())
                .relateId(afterSale.getId())
                .build());

        // 先判断商品是否是免单商品
        Spu spu = spuMapper.selectByPrimaryKey(orderSku.getSpuId());
        if (SpuTypeEnum.NORMAL.getType().equals(spu.getType())) {
            //  如果此人还未领取免单奖励，则将其排队状态设置为取消
            rewardQueueMapper.updateQueueStatusByQueueStatusAndOrderSkuId(RewardQueueStatusEnum.CANCEL.getStatus(), RewardQueueStatusEnum.QUEUING.getStatus(), orderSku.getId());
            // 无论是否领取，都将此免单商品的计数全部扣除，甚至是负数
            BonusCount bonusCount = bonusCountMapper.findOneBySpuId(orderSku.getSpuId());
            bonusCount.setCount(bonusCount.getCount() - orderSku.getCount());
            bonusCountMapper.updateByPrimaryKeySelective(bonusCount);
        }

        // 扣除商户余额，不足的则扣成负数，按orderSku中的payAmount和tenantAmount比例进行同等扣除
        BigDecimal tenantRefund = afterSale.getTenantAmount();
        if (tenantRefund.compareTo(BigDecimal.ZERO) > 0) {
            Tenant tenant = tenantMapper.selectByPrimaryKey(afterSale.getTenantId());
            tenantFlowMapper.insert(TenantFlow.builder()
                    .amount(tenantRefund)
                    .tradeType(TenantTradeTypeEnum.AFTER_SALE.getTradeType())
                    .type(TenantTradeTypeEnum.AFTER_SALE.getType())
                    .point(tenant.getPoint().subtract(tenantRefund))
                    .relateId(afterSale.getId())
                    .remark(afterSale.getProductName())
                    .createdAt(new Date())
                    .tenantId(tenant.getId())
                    .build());
            tenantMapper.updatePointById(tenant.getPoint().subtract(tenantRefund), tenant.getId());
            financeService.createFreezeAmount(orders, tenantRefund, FreezeTypeEnum.AFTER_SALE.getType());
        }

        if (SpuTypeEnum.NORMAL.getType().equals(spu.getType()) || SpuTypeEnum.ORDINARY.getType().equals(spu.getType())) {
            // 将直推嗨币扣回
            CardFlow cardFlow = cardFlowMapper.findOneByTypeAndRelateId(CardTradeTypeEnum.DIRECT_RECOMMEND_REWARD.getType(), orderSku.getId());
            if (cardFlow != null) {
                // TODO 自行关注用户的作弊行为
                User superior = userMapper.selectByPrimaryKey(cardFlow.getUserId());
                cardFlowMapper.insert(CardFlow.builder()
                        .userId(superior.getId())
                        .amount(cardFlow.getAmount())
                        .tradeType(CardTradeTypeEnum.DIRECT_RECOMMEND_REFUND.getTradeType())
                        .type(CardTradeTypeEnum.DIRECT_RECOMMEND_REFUND.getType())
                        .cardPoint(superior.getCardPoint().subtract(cardFlow.getAmount()))
                        .relateId(orderSku.getId())
                        .remark(orderSku.getProductName())
                        .createdAt(new Date())
                        .performance(orderSku.getPayAmount())
                        .build());
                userMapper.updateCardPointById(superior.getCardPoint().subtract(cardFlow.getAmount()), superior.getId());
            }
        }

        // 如果有一人退款，则将此人的新人邀请奖励设置为未奖励
        InviteFirstBuy inviteFirstBuy = inviteFirstBuyMapper.findOneByOrderSkuId(orderSku.getId());
        if (inviteFirstBuy != null) {

            if (InviteFirstBuyStatusEnum.REWARD.getStatus().equals(inviteFirstBuy.getStatus())) {
                RewardQueue rewardQueue = rewardQueueMapper.selectByPrimaryKey(inviteFirstBuy.getRewardQueueId());

                // 如果是排队中，则取消
                if (RewardQueueStatusEnum.QUEUING.getStatus().equals(rewardQueue.getQueueStatus())) {
                    // 先取消排队
                    rewardQueue.setQueueStatus(RewardQueueStatusEnum.CANCEL.getStatus());
                    rewardQueue.setUpdateAt(new Date());
                    rewardQueueMapper.updateByPrimaryKeySelective(rewardQueue);

                    // 先将所有已奖励标记为未奖励
                    inviteFirstBuyMapper.updateStatusByRewardQueueIdAndStatus(InviteFirstBuyStatusEnum.NOT_REWARD.getStatus(), rewardQueue.getId(), InviteFirstBuyStatusEnum.REWARD.getStatus());
                }
            }
            // 然后将此单的记录标记为售后取消
            inviteFirstBuy.setStatus(InviteFirstBuyStatusEnum.CANCEL.getStatus());
            inviteFirstBuyMapper.updateByPrimaryKeySelective(inviteFirstBuy);
        }

        //业绩累计扣除
        commissionService.deductAddPerformance(spu, afterSale.getRefundAmount());

        //是否撤回会员身份
        GiveMemberRecord giveMemberRecord = giveMemberRecordMapper.findOneByOrderSkuId(orderSku.getId());
        if (giveMemberRecord != null) {
            BigDecimal memberRequire = new BigDecimal(hipoConfigMapper.findValueByName(HipoConfigEnum.MEMBER_REQUIRE.getConfig()));
            if (orderSku.getPayAmount().subtract(afterSale.getRefundAmount()).compareTo(memberRequire) < 0) {
                identityMapper.updateMemberLevelAndMemberStateByUserId(UserLevelEnum.MEMBER_L1.getLevel(), MemberStateEnum.LOW.getType(), giveMemberRecord.getUserId());
            }
        }


        //修改快递助手退款状态
//        KdzsPrintTradeRefundRequest refundRequest = new KdzsPrintTradeRefundRequest();
//        refundRequest.setRefundStatus(KdzsRefundStatusEnum.REFUND_SUCCESSED.getStatus());
//        refundRequest.setMallUserId(shopMapper.selectByPrimaryKey(afterSale.getTenantId()).getMallUserId());
//        refundRequest.setTid(orders.getId().toString());
//        List<String> oidList = new ArrayList<>();
//        oidList.add(afterSale.getOrderSkuId().toString());
//        refundRequest.setOidList(oidList);
//        kuaidizsService.refundTrade(refundRequest);

        //扣除本周活动补贴
        deductMarketSubsidy(afterSale);

        //扣除本周分红
        deductDividend(afterSale, orders, spu);

        //扣除本月联合创始人分红
        deductDirectorCommission(afterSale);

        //业绩取消
        GroupsPerformance groupsPerformance = groupsPerformanceMapper.findOneByStatusAndOrderSkuId(GroupsPerformanceStatusEnum.NOT_COUNT.getStatus(), orderSku.getId());
        if (groupsPerformance != null) {
            groupsPerformance.setStatus(GroupsPerformanceStatusEnum.REFUND.getStatus());
            groupsPerformance.setUpdatedAt(new Date());
            groupsPerformanceMapper.updateByPrimaryKeySelective(groupsPerformance);
        }

        ShareholderPerformance shareholderPerformance = shareholderPerformanceMapper.findOneByStatusAndOrderSkuId(GroupsPerformanceStatusEnum.NOT_COUNT.getStatus(), orderSku.getId());
        if (shareholderPerformance != null) {
            shareholderPerformance.setStatus(ShareholderPerformanceStatusEnum.REFUND.getStatus());
            shareholderPerformance.setUpdatedAt(new Date());
            shareholderPerformanceMapper.updateByPrimaryKeySelective(shareholderPerformance);
        }
    }

    //扣除本周活动补贴
    public void deductMarketSubsidy(AfterSale afterSale) {
        Map<String, String> config = daoService.getHipoConfigMap();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);

        DividendPrecipitation dividendPrecipitation = dividendPrecipitationMapper.findOneByTypeAndStatusAndWeekTime(DividendPrecipitationTypeEnum.MARKET_SUBSIDY.getType(), DividendPrecipitationStatusEnum.NOT_GIVE.getStatus(), calendar.getTime());

        BigDecimal amount = afterSale.getRefundAmount().negate();
        BigDecimal commission = amount.multiply(new BigDecimal(config.get(HipoConfigEnum.STATIC_DIVIDEND.getConfig())));
        if (dividendPrecipitation != null) {
            dividendPrecipitationMapper.updateDividendPrecipitation(-1, amount, commission, new Date(), dividendPrecipitation.getId());
        } else {
            dividendPrecipitationMapper.insert(DividendPrecipitation.builder()
                    .type(DividendPrecipitationTypeEnum.MARKET_SUBSIDY.getType())
                    .count(-1)
                    .amount(amount)
                    .commission(commission)
                    .weekTime(calendar.getTime())
                    .status(DividendPrecipitationStatusEnum.NOT_GIVE.getStatus())
                    .updatedAt(new Date())
                    .dividendCount(0)
                    .build());
        }
    }

    //扣除本月联合创始人分红
    public void deductDirectorCommission(AfterSale afterSale) {
        Map<String, String> config = daoService.getHipoConfigMap();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);

        DividendPrecipitation dividendPrecipitation = dividendPrecipitationMapper.findOneByTypeAndStatusAndWeekTime(DividendPrecipitationTypeEnum.DIRECTOR.getType(), DividendPrecipitationStatusEnum.NOT_GIVE.getStatus(), calendar.getTime());

        BigDecimal amount = afterSale.getRefundAmount().negate();
        BigDecimal commission = amount.multiply(new BigDecimal(config.get(HipoConfigEnum.DIRECTOR_COMMISSION_RATE.getConfig())));
        if (dividendPrecipitation != null) {
            dividendPrecipitationMapper.updateDividendPrecipitation(-1, amount, commission, new Date(), dividendPrecipitation.getId());
        } else {
            dividendPrecipitationMapper.insert(DividendPrecipitation.builder()
                    .type(DividendPrecipitationTypeEnum.DIRECTOR.getType())
                    .count(-1)
                    .amount(amount)
                    .commission(commission)
                    .weekTime(calendar.getTime())
                    .status(DividendPrecipitationStatusEnum.NOT_GIVE.getStatus())
                    .updatedAt(new Date())
                    .dividendCount(0)
                    .build());
        }
    }


    //扣除本周分红
    public void deductDividend(AfterSale afterSale, Orders orders, Spu spu) {
        Map<String, String> config = daoService.getHipoConfigMap();
        String memberSpu = config.get(HipoConfigEnum.MEMBER_SPU.getConfig());
        String partnerSpu = config.get(HipoConfigEnum.PARTNER_SPU.getConfig());
        String shareholderSpu = config.get(HipoConfigEnum.SHAREHOLDER_SPU.getConfig());

        boolean isMemberSpu = spu.getId().equals(Long.valueOf(memberSpu));
        boolean isPartnerSpu = spu.getId().equals(Long.valueOf(partnerSpu));
        boolean isShareholderSpu = spu.getId().equals(Long.valueOf(shareholderSpu));
        boolean isOrdinarySpu = SpuTypeEnum.ORDINARY.getType().equals(spu.getType());
        boolean isCommissionSpu = SpuTypeEnum.COMMISSION.getType().equals(spu.getType());

        if ((isCommissionSpu && orders.getTotalPayAmount().compareTo(new BigDecimal(config.get(HipoConfigEnum.MEMBER_REQUIRE.getConfig()))) >= 0)
                || (isOrdinarySpu && (isMemberSpu || isPartnerSpu || isShareholderSpu))) {
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.HOUR_OF_DAY, 0);

            DividendPrecipitation dividendPrecipitation = dividendPrecipitationMapper.findOneByTypeAndStatusAndWeekTime(DividendPrecipitationTypeEnum.MEMBER.getType(), DividendPrecipitationStatusEnum.NOT_GIVE.getStatus(), calendar.getTime());

            BigDecimal amount = afterSale.getRefundAmount().negate();
            BigDecimal commission = amount.multiply(new BigDecimal(config.get(HipoConfigEnum.MEMBER_DIVIDENDS_1_RATE.getConfig())));
            if (dividendPrecipitation != null) {
                dividendPrecipitationMapper.updateDividendPrecipitation(-1, amount, commission, new Date(), dividendPrecipitation.getId());
            } else {
                dividendPrecipitationMapper.insert(DividendPrecipitation.builder()
                        .type(DividendPrecipitationTypeEnum.MEMBER.getType())
                        .count(-1)
                        .amount(amount)
                        .commission(commission)
                        .weekTime(calendar.getTime())
                        .status(DividendPrecipitationStatusEnum.NOT_GIVE.getStatus())
                        .updatedAt(new Date())
                        .dividendCount(0)
                        .build());
            }
        }
    }
}
